<?php

declare(strict_types=1);

namespace magein\laravel\seecms;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Str;
use magein\seecms\SeeException;
use magein\seecms\SeeResponse;
use magein\seecms\Factory;
use magein\seecms\controller\Resource;
use magein\seecms\page\Builder;
use magein\seecms\response\FileResponse;

/**
 * 资源调度器
 */
class Dispatch
{

    public function controller(Request $request): Response
    {
        $controller = $request->route()->parameter('controller');
        $action = $request->route()->parameter('action');

        $name = Str::studly($controller);
        $namespace = '\magein\seecms\controller\\' . $name;
        $class = new $namespace();

        /**
         * @var SeeResponse $response
         */
        $response = $class->$action();

        return response($response->data, $response->status_code)->withHeaders($response->header);
    }

    /**
     * 资源路由
     * @param Request $request
     * @return mixed
     * @throws SeeException
     */
    public function resource(Request $request)
    {
        $name = $request->route('name');
        $action = $request->route('action', 'page');

        $name = Str::snake($name);

        $namespace = Factory::extension()->page_provider->getPageBuild($name);

        $build_setting = null;
        if (class_exists($namespace)) {
            $build_setting = app($namespace);
        }

        if (!$build_setting instanceof Builder) {
            SeeException::json($name . ' build error');
        }

        if (empty($build_setting->getPageName())) {
            $build_setting->setPageName($name);
        }

        $resource = new Resource($build_setting);
        if (!method_exists($resource, $action)) {
            SeeException::json(400103);
        }

        /**
         * @var SeeResponse $response
         */
        $response = $resource->$action($request);

        if ($response instanceof FileResponse) {
            return response()->download($response->data);
        }

        return response($response->data, $response->status_code)->withHeaders($response->header);
    }
}
